package cn.yiyuan.car.service.impl;

import cn.yiyuan.auth.entity.EmpEntity;
import cn.yiyuan.auth.entity.ShopEntity;
import cn.yiyuan.base.customCode.Assert;
import cn.yiyuan.base.customCode.BaseConstants;
import cn.yiyuan.base.customCode.ResponseCode;
import cn.yiyuan.base.service.impl.BaseServiceImpl;
import cn.yiyuan.car.dto.CarDocRepository;
import cn.yiyuan.car.dto.Cardto;
import cn.yiyuan.car.entity.CarDetailEntity;
import cn.yiyuan.car.entity.CarEntity;
import cn.yiyuan.car.entity.CarTypeEntity;
import cn.yiyuan.car.mapper.CarDetailMapper;
import cn.yiyuan.car.mapper.CarMapper;
import cn.yiyuan.car.mapper.CarOperateLogMapper;
import cn.yiyuan.car.service.ICarService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @user m
 * @project car_mall_system
 * @date 2024-01-04
 * @package cn.yiyuan.car.service.impl
 */
@Service
public class CarServiceImpl extends BaseServiceImpl<CarEntity> implements ICarService {


    @Autowired
    private CarMapper carMapper;

    @Autowired
    private CarDetailMapper carDetailMapper;

    @Autowired
    private CarOperateLogMapper logMapper;

    @Autowired
    private CarDocRepository carDocRepository;
    @Override
    public void insert(CarEntity car, EmpEntity loginUser) {

    }

    /**
     * 批量上下架
     * @param ids
     * @param loginUser
     * @return
     */
    @Override
    public String onsale(List<Long> ids, EmpEntity loginUser) {
        // 1 参数校验   使用断言工具
        // 1.1 非空校验,如果ids为空,返回错误信息
        Assert.isNotNull(ids, ResponseCode.RESPONSE_CODE_2001);

        // 1.2 对审核状态做校验,只有下架且审核通过才可以上架
        // 思考?? 如果前端选择了10条数据,其中3条是审核驳回的,7条是审核通过的,怎么办??
        // 方案一: 只要其中有一条不满足条件,就直接返回错误信息,"请选择已审核通过的车辆进行上架"
        // 方案二: 只上架其中审核通过的,审核驳回的不上架的,如果选择这种方案, 那么你要告知前端,当前一共xx条,其中成功上架xx条,失败xx条
        //        如果想做的更好一点,可以把失败的那些车辆信息的标题返回回去 - 采纳这种
        // 1.2.1 根据ids查询出状态=下架,审核状态=通过具体的车辆信息
        List<CarEntity> list = carMapper.queryByIdsAndCondition(ids);
        // 1.2.2 如果list为空,说明当前没有一个数据满足条件的,就返回错误信息
        Assert.isNotNull(list,ResponseCode.RESPONSE_CODE_2001);
        String msg = "本次一共操作%s条数据,其中成功上架%s条,失败%s条.";
        msg = String.format(msg,ids.size(),list.size(),ids.size() - list.size());
        // 思考??  先操作数据库还是先操作es??
        // 先操作数据库, 因为如果你先操作es,万一后面操作数据库报错了,es是不好回滚的
        // 2  修改数据库的状态=上架,上架时间=当前时间
        // 2.1 获取当前满足条件的id
        List<Long> onsaleIds = list.stream().map(CarEntity::getId).collect(Collectors.toList());
        // 2.2 修改数据库状态
        // 上架要批量修改数据库的状态和时间,下架也要批量修改数据库的状态和时间,怎么办??
        // update table set state = 1 ,onsaletime = now() where id in ()
        // update table set state = 0 ,offsaletime = now() where id in ()
        // 方案一: 写两个mapper方法,一个上架,一个下架
        // 方案二: 传两个参数,一个是ids,还有一个是状态,在mapper.xml中通过状态判断,如果是上架就修改状态=1,并修改上架时间
        carMapper.batchUpdateState(onsaleIds, BaseConstants.Car.CAR_STATE_ONSALE);

        // 3 将数据添加到es
        List<Cardto> docs = buildCarDocs(list);
        carDocRepository.saveAll(docs);
        // 4 添加上架的操作日志,当前上架了几条数据,就要添加几个操作日志,操作日志是和车辆ID挂钩的


        return null;
    }

    private List<Cardto> buildCarDocs(List<CarEntity> list) {
        List<Cardto> docs = new ArrayList<>();
        for (CarEntity car : list) {
            Cardto doc = new Cardto();
            // 通过car对象复制一个doc对象
            BeanUtils.copyProperties(car,doc);

            // 处理车辆类型
            CarTypeEntity carType = car.getCarType();
            if(Objects.nonNull(carType)){
                doc.setTypeId(carType.getId());
                doc.setTypeName(carType.getName());
            }

            // 处理店铺信息
            ShopEntity shop = car.getShop();
            if(Objects.nonNull(shop)){
                doc.setShopId(shop.getId());
                doc.setShopName(shop.getName());
                doc.setShopAddress(shop.getAddress());
                doc.setLatitude(shop.getLat());
                doc.setLongitude(shop.getLng());
            }

            // 处理详情信息
            CarDetailEntity carDetail = car.getCarDetailEntity();
            if(Objects.nonNull(carDetail)){
                doc.setCarInfo(carDetail.getInfo());
            }

            docs.add(doc);
        }
        return docs;
    }

    @Override
    public void offsale(List<Long> ids, EmpEntity loginUser) {

    }
}
